package meterMonitor.biz;

import meterMonitor.mapper.AreaMapper;
import meterMonitor.mapper.MeterMapper;
import meterMonitor.mapper.MonitorMapper;
import meterMonitor.model.Area;
import meterMonitor.model.Meter;
import meterMonitor.model.Monitor;
import meterMonitor.model.MonitorDetail;
import meterMonitor.util.BizUtil;
import meterMonitor.util.DateUtils;
import meterMonitor.util.ResourceConfig;
import meterMonitor.util.excel.ExcelUtil;
import meterMonitor.util.excel.domain.ExcelColumn;
import meterMonitor.vo.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by admin on 2018/12/30.
 */
@Service
public class MonitorBiz extends BaseBiz {

    @Autowired
    private MonitorMapper monitorMapper;
    @Autowired
    private MeterMapper meterMapper;
    @Autowired
    BizUtil bizUtil;
    @Autowired
    protected ResourceConfig resourceConfig;

    @Autowired
    private AreaMapper areaMapper;


    /**
     * 查询本周用量
     *
     * @return
     */
    public List<MeterStatistics> selectWeek() {
        //设置日期的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        //得到今天
        Date strDate = new Date();
        //本周第一天
        String firstStr = DateUtils.getNowWeekBegin();
        //将日期转换为字符串格式
        String strDate2 = sdf1.format(strDate);

        Date d1 = new Date();
        try {
            //parse方法可以把String型的字符串转换成特定格式的date类型，
            // 使用parse时字符串长度要和定义的SimpleDateFormat对象长度一致
            d1 = sdf.parse(strDate2);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //得到这天属于该周的第几天
        Calendar cal = Calendar.getInstance();
        cal.setTime(strDate);
        //属于第 day 天
        int day = cal.get(Calendar.DAY_OF_WEEK) - 1;
        //得到几天前的时间
        String begin = sdf.format(DateUtils.getDateBefore(d1, 6));
        String strDate1 = sdf.format(strDate);
        List<MeterStatistics> list = null;
        //
        if (day == 0) {
            list = meterMapper.selectWeekYesterday(begin, strDate1);
        } else {
            list = meterMapper.selectWeekYesterday(firstStr, strDate1);
        }

        return list;
    }

    /**
     * 查询本周用量
     *
     * @return
     */
    public List<MeterStatistics> selectMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date first = DateUtils.getMonthStartTime();
        Date lated = new Date();

        String firstStr = sdf.format(first);
        String latedStr = sdf.format(lated);

        List<MeterStatistics> list = meterMapper.selectMonthMon(firstStr, latedStr);

//        List<MeterStatistics> list = null;
//        //得到昨天
//        String strDate =  sdf.format(bizUtil.GetYestordayDate());
//        //得到今天
//        String nestrDate =  DateUtils.format(new Date(),"yyyy-MM-dd");
//
//        //本月开始日期
//        String begin =  BizUtil.getMonthStart();
//        String big = nestrDate.substring(8,10);
//        if (big.equals("01")){
//            //获取上个月最后一天
//            String lastday = bizUtil.getMonthStartE();
//            //获取上月第一天
//            String fastday = bizUtil.getMonthStartK();
//
//            //查上个月所有数据
//            list = meterMapper.selectMonthMon(fastday,lastday);
//        }else {
//            list =  meterMapper.selectMonthMon(begin,strDate);
//        }

        return list;
    }


    /**
     * @param strDate    日期
     * @param dayOrNight 班次
     * @return 实时状态数据
     */
    public List<RealTimeFlow> getRealTimeFlows(String strDate, String dayOrNight, String areaId) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("strDate", strDate);
        map.put("dayOrNight", dayOrNight);
        map.put("areaId", areaId);
        List<RealTimeFlow> realTimeFlows = monitorMapper.getRealTimeFlows(map);
        return realTimeFlows;
    }

    //region 报表查询

    /**
     * @param fromDate     开始日期
     * @param toDate       结束日期
     * @param anotherNames 设备名称
     * @param shiftCode    班次
     * @return 日报表
     */
    public List<ReportDaily> getReportDaily(String fromDate, String toDate, String shiftCode, String anotherNames[]) {
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        List<ReportDaily> lists = monitorMapper.getReportDaily(fromDate, toDate, shiftCode, anotherNames);
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        for (ReportDaily mod : lists) {
            Double electricQty = mod.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                mod.setElectricQtyShow(electricQty + "%");
            }
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(rate));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    /**
     * @param fromDate     开始日期
     * @param toDate       结束日期
     * @param anotherNames 设备代号
     * @return 月报表
     */
    public List<ReportMonthly> getReportMonthly(String fromDate, String toDate, String[] anotherNames) {
        List<ReportMonthly> lists = new LinkedList<>();
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        int min = 0;
        try {
            Date date1 = format.parse(fromDate);
            Date date2 = format.parse(toDate);
            min = DateUtils.getOffsetDays(date1, date2);
        } catch (ParseException e) {
            e.printStackTrace();
        }


        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        try {
            lists = monitorMapper.getReportMonthly(fromDate, toDate, anotherNames);
        } catch (Exception e) {
            e.printStackTrace();
        }
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        for (ReportMonthly mod : lists) {
            Double electricQty = mod.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                mod.setElectricQtyShow(electricQty + "%");
            }
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            double standard = mod.getStandardUsage();
            mod.setStandardUsage(standard * (min + 1));

            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));

            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(mod.getSaveRate()));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    /**
     * @param fromDate     开始日期
     * @param toDate       结束日期
     * @param anotherNames 设备代号
     * @param shiftCode    班次
     * @return 日报表
     */
    public List<ReportDaily> getReportDailySum(String fromDate, String toDate, String shiftCode, String anotherNames[]) {
        List<ReportDaily> lists = new LinkedList<>();
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        try {
            lists = monitorMapper.getReportDailySum(fromDate, toDate, shiftCode, anotherNames);
            if (lists != null) {
                for (ReportDaily reportDaily : lists) {
                    double standard = reportDaily.getStandardUsage();
                    Double electricQty = reportDaily.getElectricQty();
                    if (electricQty != null) {
                        electricQty = Double.valueOf(df.format(electricQty));
                        reportDaily.setElectricQtyShow(electricQty + "%");
                    }
                    double realUsage = reportDaily.getRealUsage();
                    reportDaily.setRealUsage(Double.valueOf(df.format(realUsage)));
                    if (reportDaily.getStandardUsage() == null) {
                        reportDaily.setStandardUsage(0D);
                    }
                }
            }
        } catch (Exception e) {
            this.logger.error(e.getMessage(), e);
            e.printStackTrace();
        }
        //
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        if (lists != null) {
            for (ReportDaily mod : lists) {
                if (mod.getElectricQty() == null) {
                    mod.setElectricQty(0d);
                }
                if (mod.getRealUsage() == null) {
                    mod.setRealUsage(0d);
                }
                if (mod.getStandardUsage() == null) {
                    mod.setStandardUsage(0D);
                }
                if (mod.getExceedSec() == null) {
                    mod.setExceedSec(0D);
                }
                Double currentQuantiry = mod.getCurrentQuantiry();
                if (currentQuantiry != null) {
                    currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                    mod.setCurrentQuantiry(currentQuantiry);
                }
                mod.setRealUsageShow(df.format(mod.getRealUsage()));
                mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
                //用水节约率
                double rate = 0;
                if (mod.getStandardUsage() > 0) {
                    rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
                }
                mod.setSaveRate(rate);
                mod.setSaveRateShow(new DecimalFormat("#.##%").format(mod.getSaveRate()));
                //是否超标
                boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
                mod.setOverFlow(isOF);
                mod.setOverFlowName(isOF ? "是" : "否");
                //超标时长
                if (mod.getExceedSec() == null) {
                    //mod.setExceedSec(Double.valueOf(0));
                    mod.setExceedHourShow("0");
                }

                mod.setExceedHour(mod.getExceedSec() / 3600);
                System.out.println(mod.getExceedSec());
                System.out.println("===" + mod);

                mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
            }
        }
        return lists;
    }

    /**
     * @param fromDate     开始日期
     * @param toDate       结束日期
     * @param anotherNames 设备代号
     * @return 月报表
     */
    public List<ReportMonthly> getReportMonthlySum(String fromDate, String toDate, String[] anotherNames) {
        List<ReportMonthly> lists = new LinkedList<>();
        Date d1, d2;
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");


        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        List<ReportMonthly> list = this.getReportMonthly(fromDate, toDate, anotherNames);
        double r = 0d;
        for (ReportMonthly reportMonthly : list) {
            r = reportMonthly.getStandardUsage() + r;

        }
        try {
            lists = monitorMapper.getReportMonthlySum(fromDate, toDate, anotherNames);
            for (ReportMonthly reportMonthly : lists) {
                Double electricQty = reportMonthly.getElectricQty();
                if (electricQty != null) {
                    electricQty = Double.valueOf(df.format(electricQty));
                    reportMonthly.setElectricQtyShow(electricQty + "%");
                }
                double realUsage = reportMonthly.getRealUsage();
                reportMonthly.setRealUsage(Double.valueOf(df.format(realUsage)));
                if (reportMonthly.getStandardUsage() == null) {
                    reportMonthly.setStandardUsage(0D);
                }


            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        for (ReportMonthly mod : lists) {
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            double standard = mod.getStandardUsage();
            //mod.setStandardUsage(standard*(min+1));
            mod.setStandardUsage(r);

            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(mod.getSaveRate()));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    //endregion

    /**
     * 查询日报表
     *
     * @param requestMod
     * @return
     */
    public List<Monitor> queryForDayChart(QueryForChartRequest requestMod) {
        if (requestMod.getEndDate().equals(requestMod.getStartDate())) {
            return null;
        }
        if (requestMod.getType() == 40) {
            return null;
        }
        if (requestMod.getAnotherName() != null) {
            boolean isAll = false;
            for (String no : requestMod.getAnotherName()) {
                if (no.equals("-1")) {
                    isAll = true;
                    break;
                }
            }
            if (isAll) {
                requestMod.setAnotherName(null);
            }
        }

        List<Monitor> list = monitorMapper.queryForDayCharts(requestMod);
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        for (Monitor monitor : list) {
            Double electricQty = monitor.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                monitor.setElectricQty(electricQty);
            }
            Double currentQuantiry = monitor.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                monitor.setCurrentQuantiry(currentQuantiry);
            }

        }
        return list;
    }

    /**
     * 班次  图表
     *
     * @param requestMod
     * @return
     */
    public Map queryForDay(QueryForChartRequest requestMod) {
        if (requestMod.getType() == 40) {
            return null;
        }
        if (requestMod.getAnotherName() != null) {
            boolean isAll = false;
            for (String no : requestMod.getAnotherName()) {
                if (no.equals("-1")) {
                    isAll = true;
                    break;
                }
            }
            if (isAll) {
                requestMod.setAnotherName(null);
            }
        }

        List<MonitorMeter> list = monitorMapper.queryFor(requestMod);
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        for (MonitorMeter monitorMeter : list) {
            monitorMeter.setIntervalQuantity(Double.valueOf(df.format(monitorMeter.getIntervalQuantity())));
        }
        Map resultMap = this.formatChart(requestMod, list);
        return resultMap;
    }

    public Map queryForOwnerTimer(QueryForChartRequest requestMod) {
        if (requestMod.getAnotherName() != null) {
            boolean isAll = false;
            for (String no : requestMod.getAnotherName()) {
                if (no.equals("-1")) {
                    isAll = true;
                    break;
                }
            }
            if (isAll) {
                requestMod.setAnotherName(null);
            }
        }
        List<MonitorMeter> list = monitorMapper.queryForOwnerTimer(requestMod);
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        for (MonitorMeter monitorMeter : list) {
            monitorMeter.setIntervalQuantity(Double.valueOf(df.format(monitorMeter.getIntervalQuantity())));
        }
        Map resultMap = this.formatChartForOwnerTimer(requestMod, list);
        return resultMap;
    }


    private Map formatChart(QueryForChartRequest requestMod, List<MonitorMeter> data) {
        Map<String, Object> map = new HashMap<>();
        List<MonitorMeter> resultList = new ArrayList<MonitorMeter>();
        List<String> meterNames = this.getMeterNames(requestMod);
        Date sDate = DateUtils.parse(requestMod.getStartDate(), DateUtils.PATTERN_CLASSICAL_SIMPLE);
        Date eDate = DateUtils.parse(requestMod.getEndDate(), DateUtils.PATTERN_CLASSICAL_SIMPLE);
        int cnt = DateUtils.getOffsetDays(sDate, eDate);
        String sDateStr;
        Date vDate;
        MonitorMeter mod;
        List<String> dateList = new ArrayList<>();
        List<Map> dataList = new ArrayList<>();
        List<Double> qty;
        List<Double> std;
        Map<String, Object> mapData;
        boolean isSetDate = false;
        for (String name : meterNames) {
            vDate = sDate;
            qty = new ArrayList<>();
            std = new ArrayList<>();
            mapData = new HashMap<>();
            for (int i = 0; i <= cnt; i++) {
                sDateStr = DateUtils.format(vDate, DateUtils.PATTERN_CLASSICAL_SIMPLE);
                if (!isSetDate) {
                    dateList.add(sDateStr);
                }
                vDate = DateUtils.addDays(vDate, 1);
                mod = this.generateMM(data, name, sDateStr);
                qty.add(mod.getIntervalQuantity());
                std.add(mod.getStandard());
                resultList.add(mod);
            }
            mapData.put(name, qty);
            mapData.put(name + "标准量", std);
            dataList.add(mapData);
            isSetDate = true;
        }
        map.put("dates", dateList);
        map.put("datas", dataList);
        return map;
        // return resultList;
    }

    private Map formatChartForOwnerTimer(QueryForChartRequest requestMod, List<MonitorMeter> data) {
        Map<String, List<Double>> mapData = new HashMap<>();
        List<String> dateList = new ArrayList<>();
        List<Map> dataList = new ArrayList<>();
        List<String> meterNames = new ArrayList<>(); // 保存已经记录的水表名称
        for (MonitorMeter m : data) {
            if (!dateList.contains(m.getOwnerTimerStr())) {
                dateList.add(m.getOwnerTimerStr());
            }
            if (mapData.containsKey(m.getAnotherName())) {
                mapData.get(m.getAnotherName()).add(m.getIntervalQuantity());
            } else {
                List<Double> qty = new ArrayList<>();
                qty.add(m.getIntervalQuantity());
                mapData.put(m.getAnotherName(), qty);
            }
            if(!meterNames.contains(m.getAnotherName())){
                meterNames.add(m.getAnotherName());
                dataList.add(mapData);
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("dates", dateList);
        map.put("datas", dataList);
        return map;
    }

    private MonitorMeter generateMM(List<MonitorMeter> data, String meterName, String dateStr) {
        MonitorMeter mod;
        for (MonitorMeter model : data) {
            if (model.getAnotherName().equals(meterName) && model.getUploadDateStr().equals(dateStr)) {
                return model;
            }
        }
        mod = new MonitorMeter();
        mod.setAnotherName(meterName);
        mod.setUploadDateStr(dateStr);
        mod.setIntervalQuantity(0D);
        mod.setIntervalSec(0D);
        mod.setStandard(0);
        mod.setMonthMeterStandar(0);
        return mod;
    }

    public List<String> getMeterNames(QueryForChartRequest requestMod) {
        if (requestMod.getAnotherName() == null) {
            List<Meter> list = this.meterMapper.queryAllMeter();
            List<String> result = new ArrayList<String>();
            for (Meter meter : list) {
                result.add(meter.getAnotherName());
            }
            return result;
        }
        return requestMod.getAnotherName();
    }

    /**
     * 查询月报表 图表
     *
     * @param requestMod
     * @return
     */
    public Map queryForMonthChart(QueryForChartRequest requestMod) {
        List<Meter> meters = new ArrayList<>();
        List<String> listRe = new ArrayList<>();
        // List<MonitorMeter> listReturn = new ArrayList<>();
        if (requestMod.getType() != 40) {
            return null;
        }
        if (requestMod.getAnotherName() != null) {
            boolean isAll = false;
            for (String no : requestMod.getAnotherName()) {
                if (no.equals("-1")) {
                    isAll = true;
                    break;
                }
            }
            if (isAll) {
                requestMod.setAnotherName(null);
                meters = meterMapper.queryAllMeter();
                for (Meter m : meters) {
                    listRe.add(m.getAnotherName());
                    MonitorMeter monitorMeter = new MonitorMeter();
                    monitorMeter.setAnotherName(m.getAnotherName());
                    //listReturn.add(monitorMeter);
                }
            } else {
                //请求中的设备
                listRe = requestMod.getAnotherName();
                for (String listre : listRe) {
                    MonitorMeter monitorMeter = new MonitorMeter();
                    monitorMeter.setAnotherName(listre);
                    //listReturn.add(monitorMeter);
                }
            }
        }

        //获取选择日期
//        String startStr = requestMod.getStartDate();
//        String endStr = requestMod.getEndDate();
//        String startd = startStr.substring(5, 7);
//        String endd = endStr.substring(5, 7);
//        String starty = startStr.substring(0,4);
//        String endy = endStr.substring(0,4);

//        int start = Integer.valueOf(starty + startd);
//        int end = Integer.valueOf(endy+endd);
        // List<String> listDB = new ArrayList<>();
        List<MonitorMeter> list = monitorMapper.queryForMonth(requestMod);
//        List<MonitorMeter> listr = new ArrayList<>();
//        for (MonitorMeter monitorMeter:list){
//            listDB.add(monitorMeter.getAnotherName());
//        }
//        int i = start;
//        for (i=start;i<=end;i++){
//            listRe.removeAll(listDB);
//            for (MonitorMeter monitorMeter:list){
//                String uploadStr = monitorMeter.getUploadDateStr();
//              String y = uploadStr.substring(0, 4);
//               String d = uploadStr.substring(5,7);
//               String upload = y+d;
//                if (upload.equals(String.valueOf(i))){
//                    MonitorMeter monitorMeter1 = new MonitorMeter();
//                    monitorMeter1.setAnotherName(monitorMeter.getAnotherName());
//                    monitorMeter1.setIntervalQuantity(monitorMeter.getIntervalQuantity());
//                    monitorMeter1.setUploadDateStr(monitorMeter.getUploadDateStr());
//                    listReturn.add(monitorMeter1);
//
//                }
//
//
//            }
//            List<String> list1 = new ArrayList<>();
//            for (MonitorMeter monitorMeter:listReturn){
//                list1.add(monitorMeter.getAnotherName());
//            }
//            listRe.removeAll(list1);
//            for (String a:listRe){
//                MonitorMeter monitorMeter = new MonitorMeter();
//                monitorMeter.setIntervalQuantity(0d);
//                monitorMeter.setUploadDateStr(String.valueOf(i));
//                monitorMeter.setAnotherName(a);
//                listReturn.add(monitorMeter);
//            }
//
//        }


        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        for (MonitorMeter monitorMeter : list) {
            monitorMeter.setIntervalQuantity(Double.valueOf(df.format(monitorMeter.getIntervalQuantity())));
            monitorMeter.setStandard(Double.valueOf(df.format(monitorMeter.getStandard())));
        }

        Map resultMap = this.formatChartMonth(requestMod, list);
        return resultMap;
        //return listReturn;
    }


    private Map formatChartMonth(QueryForChartRequest requestMod, List<MonitorMeter> data) {
        Map<String, Object> map = new HashMap<>();
        List<MonitorMeter> resultList = new ArrayList<MonitorMeter>();
        List<String> meterNames = this.getMeterNames(requestMod);
        Date sDate = DateUtils.parse(requestMod.getStartDate(), DateUtils.PATTERN_CLASSICAL_SIMPLE);
        Date eDate = DateUtils.parse(requestMod.getEndDate(), DateUtils.PATTERN_CLASSICAL_SIMPLE);
        // int cnt=DateUtils.getOffsetDays(sDate,eDate);
        int cnt = 5000;
        String sDateStr;
        Date vDate;
        MonitorMeter mod;
        List<String> dateList = new ArrayList<>();
        List<Map> dataList = new ArrayList<>();
        List<Double> qty;
        List<Double> std;
        Map<String, Object> mapData;
        boolean isSetDate = false;
        for (String name : meterNames) {
            vDate = sDate;
            qty = new ArrayList<>();
            std = new ArrayList<>();
            mapData = new HashMap<>();
            for (int i = 0; i < cnt; i++) {
                if ((vDate.getMonth() > eDate.getMonth() && vDate.getYear() == eDate.getYear()) || vDate.getYear() > eDate.getYear()) {
                    break;
                }
                sDateStr = DateUtils.format(vDate, DateUtils.PATTERN_CLASSICAL_SIMPLE).substring(0, 7);

                if (!isSetDate) {
                    dateList.add(sDateStr);
                }
                mod = this.generateMM(data, name, sDateStr);
                qty.add(mod.getIntervalQuantity());
                std.add(mod.getStandard());
                resultList.add(mod);
                vDate = DateUtils.rollMonth(vDate, 1);
            }
            mapData.put(name, qty);
            mapData.put(name + "标准量", std);
            dataList.add(mapData);
            isSetDate = true;
        }
        map.put("dates", dateList);
        map.put("datas", dataList);
        return map;
        // return resultList;
    }

    /**
     * 查询月报表 综合
     *
     * @param requestMod
     * @return
     */
    public List<MonitorMeter> queryForMonth(QueryForChartRequest requestMod) {
        if (requestMod.getType() != 40) {
            return null;
        }
        if (requestMod.getAnotherName() != null) {
            if (requestMod.getAnotherName().contains("-1")) {
                requestMod.setAnotherName(null);
            }
        }
        List<MonitorMeter> list = monitorMapper.queryForMonthCharts(requestMod);
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        for (MonitorMeter monitorMeter : list) {
            monitorMeter.setIntervalQuantity(Double.valueOf(df.format(monitorMeter.getIntervalQuantity())));
        }
        return list;
    }

    /**
     * 查询当天所有上传数据
     *
     * @param strDate
     * @param dayOrNight
     * @param areaId     区域ID
     * @return List<RealTimeFlow>
     */
    public List<RealTimeFlow> getMonitorDetail(String strDate, String dayOrNight, String areaId) {
        Map<String, MonitorDetail> map = new HashMap<>();
        String str = resourceConfig.getValueByKey("offline_minutes");
        int minutes = Integer.valueOf(str);
        String endtime;
        Date date = new Date();
        endtime = DateUtils.format(date, "yyyy-MM-dd HH:mm:ss");

        Date d = DateUtils.addMinutes(new Date(), -minutes);
        String startStr = DateUtils.format(d, DateUtils.PATTERN_CLASSICAL);
        //获取当天流量
        List<RealTimeFlow> relist = getRealTimeFlows(strDate, dayOrNight, areaId);
        //查询非离线上传数据的读表器编号
        List<String> molist = monitorMapper.getMonitorDetail(getOfflineTime());
        for (RealTimeFlow er : relist) {
            if (!molist.contains(er.getMeterCode()))
                er.setLight(true);
        }
        return relist;
    }

    public List<ExcelColumn> headersOfDIYRep() {
        List<ExcelColumn> list = new LinkedList<>();
        list.add(new ExcelColumn(0, "strDate", ""));
        /*for (MeterInfoShort meter : meterMapper.queryMetersInfoShort()) {
            list.add(new ExcelColumn(0, meter.getDeviceName(), meter.getAreaName()));
        }*/
        List<MeterInfoShort> meterInfos = meterMapper.queryMetersInfoShort();
        for (int i = 0; i < meterInfos.size(); i++) {
            MeterInfoShort meter = meterInfos.get(i);
            if (i > 0) {
                MeterInfoShort meterBef = meterInfos.get(i - 1);
                if (!meter.getAreaId().equalsIgnoreCase(meterBef.getAreaId())) {
                    list.add(new ExcelColumn(0, meterBef.getAreaId(), meterBef.getAreaName()));
                }
            }
            list.add(new ExcelColumn(0, meter.getDeviceName(), meter.getAreaName()));
        }
        //
        return list;
    }

    public List<Map<String, Object>> queryDIYRep(String startDate, String endDate) {
        List<Map<String, Object>> list = new LinkedList<>();
        Map<String, String> header = new HashMap<>();

        //region 构造日期列表
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date fromDate = new Date();
        Date toDate = fromDate;
        try {
            fromDate = simpleDateFormat.parse(startDate);
            toDate = simpleDateFormat.parse(endDate);
        } catch (ParseException e) {
            //e.printStackTrace();
        }
        List<String> dateList = new LinkedList<>();
        for (Date d = fromDate; d.before(DateUtils.addDays(toDate, 1)); d = DateUtils.addDays(d, 1)) {
            dateList.add(simpleDateFormat.format(d));
        }
        //endregion

        //region 构造 Map<水表,Map<日期,DIYRepExport>>
        Map<String, Map<String, DIYRepExport>> tempMap = new HashMap<>();
        for (DIYRepExport mod : monitorMapper.queryForDIYRep(startDate, endDate)) {
            Map<String, DIYRepExport> map = tempMap.get(mod.getMeterCode());
            if (map == null) {
                map = new HashMap<>();
                tempMap.put(mod.getMeterCode(), map);
            }
            //
            if (!map.containsKey(mod.getUploadDate())) {
                map.put(mod.getUploadDate(), mod);
            }
        }
        //endregion

        DecimalFormat decimalFormat = new DecimalFormat("#0.#");
        //按 区域、水表排序
        List<MeterInfoShort> meterInfos = meterMapper.queryMetersInfoShort();
        //region 首行数据 = 水表名称
        Map<String, Object> rowHeader = new HashMap();
        rowHeader.put("strDate", "日期");
        for (int i = 0; i < meterInfos.size(); i++) {
            MeterInfoShort meter = meterInfos.get(i);
            if (i > 0) {
                MeterInfoShort meterBef = meterInfos.get(i - 1);
                if (!meter.getAreaId().equalsIgnoreCase(meterBef.getAreaId())) {
                    rowHeader.put(meterBef.getAreaId(), "累计");
                }
            }
            rowHeader.put(meter.getDeviceName(), meter.getAnotherName());
        }
        list.add(rowHeader);
        //endregion

        //
        for (String d : dateList) {
            //行数据
            Map<String, Object> row = new HashMap<String, Object>();
            row.put("strDate", d);
            Double total = 0d;
            for (int i = 0; i < meterInfos.size(); i++) {
                MeterInfoShort meter = meterInfos.get(i);
                if (i > 0) {
                    MeterInfoShort meterBef = meterInfos.get(i - 1);
                    if (!meter.getAreaId().equalsIgnoreCase(meterBef.getAreaId())) {
                        row.put(meterBef.getAreaId(), Double.valueOf(decimalFormat.format(total)));
                        total = 0d;
                    }
                }
                Map<String, DIYRepExport> mm1 = tempMap.get(meter.getDeviceName());
                if (mm1 != null && mm1.containsKey(d)) {
                    DIYRepExport mod = mm1.get(d);
                    //
                    total += mod.getIntervalQuantity();
                    row.put(meter.getDeviceName(), Double.valueOf(decimalFormat.format(mod.getIntervalQuantity())));
                } else {
                    row.put(meter.getDeviceName(), "");
                    //
                    total += 0;
                }
            }
            //
            list.add(row);
        }

        //region 计算累计值
        MeterInfoShort meter01 = null;
        MeterInfoShort meter10 = null;
        MeterInfoShort meter07 = null;
        //一厂生产用水=01#上级分类
        String fac1ProdCode = "";
        //一厂公共用水=07#上级分类
        String fac1PubCode = "";
        //一厂环保用水=10#上级分类
        String fac1EnvCode = "";
        for (MeterInfoShort meterInfoShort : meterInfos) {
            //取01#水表的上级分类代号
            if (meterInfoShort.getAnotherName().startsWith("01#")) {
                meter01 = meterInfoShort;
                fac1ProdCode = meterInfoShort.getAreaId();
            }
            //取07#水表的上级分类代号
            if (meterInfoShort.getAnotherName().startsWith("07#")) {
                meter07 = meterInfoShort;
                fac1PubCode = meterInfoShort.getAreaId();
            }
            //取10#新回收房水表的上级分类代号
            if (meterInfoShort.getAnotherName().startsWith("10#")) {
                meter10 = meterInfoShort;
                fac1EnvCode = meterInfoShort.getAreaId();
            }
        }
        for (int i = 1; i < list.size(); i++) {
            Map<String, Object> map = list.get(i);
            Double meter07Value = 0d;
            String v0 = map.get(meter07.getDeviceName()).toString();
            if (!StringUtils.isBlank(v0)) {
                meter07Value = Double.valueOf(v0);
            }
            Double fac1PubValue = 0d;
            String v1 = map.get(fac1PubCode).toString();
            if (StringUtils.isNotBlank(v1)) {
                fac1PubValue = Double.valueOf(v1);
            }
            Double fac1EnvValue = 0d;
            String v2 = map.get(fac1EnvCode).toString();
            if (StringUtils.isNotBlank(v2)) {
                fac1EnvValue = Double.valueOf(v2);
            }
            Double fac1ProdValue = 0d;
            String v3 = map.get(fac1ProdCode).toString();
            if (StringUtils.isNotBlank(v3)) {
                fac1ProdValue = Double.valueOf(v3);
            }
            //一厂公共用水排除07#水表
            map.put(fac1PubCode, decimalFormat.format(fac1PubValue - meter07Value));
            //一厂生产用水排除 一厂环保用水和07#水表
            map.put(fac1ProdCode, decimalFormat.format(fac1ProdValue - fac1EnvValue - meter07Value));
        }
        //endregion

        return list;
    }

    public void queryDIYRep2(String startDate, String endDate, HttpServletResponse response) {
        List<Map<String, Object>> list = new LinkedList<>();
        Map<String, String> header = new HashMap<>();

        //region 构造日期列表-dateList
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date fromDate = new Date();
        Date toDate = fromDate;
        try {
            fromDate = simpleDateFormat.parse(startDate);
            toDate = simpleDateFormat.parse(endDate);
        } catch (ParseException e) {
            //e.printStackTrace();
        }
        List<String> dateList = new LinkedList<>();
        for (Date d = fromDate; d.before(DateUtils.addDays(toDate, 1)); d = DateUtils.addDays(d, 1)) {
            dateList.add(simpleDateFormat.format(d));
        }
        //endregion

        //region 构造 Map<日期,Map<水表,DIYRepExport>>-tempMap
        Map<String, Map<String, DIYRepExport>> tempMap = new HashMap<>();
        for (DIYRepExport mod : monitorMapper.queryForDIYRep(startDate, endDate)) {
            Map<String, DIYRepExport> map = tempMap.get(mod.getUploadDate());
            if (map == null) {
                map = new HashMap<>();
                tempMap.put(mod.getUploadDate(), map);
            }
            //
            if (!map.containsKey(mod.getMeterCode())) {
                map.put(mod.getMeterCode(), mod);
            }
        }
        //endregion

        //region 构造区域、水表Ma-areaMap(按 区域、水表排序)
        List<MeterInfoShort> meterInfos = meterMapper.queryMetersInfoShort();
        Map<String, Map<String, MeterInfoShort>> areaMap = new HashMap<>();
        for (MeterInfoShort mod : meterInfos) {
            Map<String, MeterInfoShort> mmp = areaMap.get(mod.getAreaId());
            if (!areaMap.containsKey(mod.getAreaId())) {
                mmp = new HashMap<>();
                areaMap.put(mod.getAreaId(), mmp);
            }
            //
            mmp.put(mod.getDeviceName(), mod);
        }
        //endregion

        ExcelUtil.getInstanse().exportDIYReport(tempMap, areaMap, response);
    }

    public List<Map<String, String>> queryDIYRep2(String startDate, String endDate) {
        List<Map<String, String>> list = new LinkedList<>();
        Map<String, String> header = new HashMap<>();

        //region 构造日期列表
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

        List<String> dateList = getDates(startDate, endDate);

        //endregion

        //region 构造 Map<水表,Map<日期,DIYRepExport>>
        Map<String, Map<String, DIYRepExport>> tempMap = new HashMap<>();
        for (DIYRepExport mod : monitorMapper.queryForDIYRep(startDate, endDate)) {
            Map<String, DIYRepExport> map = tempMap.get(mod.getMeterCode());
            if (map == null) {
                map = new HashMap<>();
                tempMap.put(mod.getMeterCode(), map);
            }
            //
            if (!map.containsKey(mod.getUploadDate())) {
                map.put(mod.getUploadDate(), mod);
            }
        }
        //endregion

        DecimalFormat decimalFormat = new DecimalFormat("#0.#");
        //按 区域、水表排序
        List<MeterInfoShort> meterInfos = meterMapper.queryMetersInfoShort();
        //region 首行数据 = 水表名称
        Map<String, String> rowHeader = new HashMap<String, String>();
        rowHeader.put("strDate", "日期");
        for (int i = 0; i < meterInfos.size(); i++) {
            MeterInfoShort meter = meterInfos.get(i);
            if (i > 0) {
                MeterInfoShort meterBef = meterInfos.get(i - 1);
                if (!meter.getAreaId().equalsIgnoreCase(meterBef.getAreaId())) {
                    rowHeader.put(meterBef.getAreaId(), "累计");
                }
            }
            rowHeader.put(meter.getDeviceName(), meter.getAnotherName());
        }
        list.add(rowHeader);
        //endregion

        //
        for (String d : dateList) {
            //行数据
            Map<String, String> row = new HashMap<String, String>();
            row.put("strDate", d);
            Double total = 0d;
            for (int i = 0; i < meterInfos.size(); i++) {
                MeterInfoShort meter = meterInfos.get(i);
                if (i > 0) {
                    MeterInfoShort meterBef = meterInfos.get(i - 1);
                    if (!meter.getAreaId().equalsIgnoreCase(meterBef.getAreaId())) {
                        row.put(meterBef.getAreaId(), String.valueOf(decimalFormat.format(total)));
                        total = 0d;
                    }
                }
                Map<String, DIYRepExport> mm1 = tempMap.get(meter.getDeviceName());
                if (mm1 != null && mm1.containsKey(d)) {
                    DIYRepExport mod = mm1.get(d);
                    //
                    total += mod.getIntervalQuantity();
                    row.put(meter.getDeviceName(), String.valueOf(decimalFormat.format(mod.getIntervalQuantity())));
                } else {
                    row.put(meter.getDeviceName(), "");
                    //
                    total += 0;
                }
            }
            //
            list.add(row);
        }

        //region 计算累计值
        MeterInfoShort meter01 = null;
        MeterInfoShort meter10 = null;
        MeterInfoShort meter07 = null;
        //一厂生产用水=01#上级分类
        String fac1ProdCode = "";
        //一厂公共用水=07#上级分类
        String fac1PubCode = "";
        //一厂环保用水=10#上级分类
        String fac1EnvCode = "";
        for (MeterInfoShort meterInfoShort : meterInfos) {
            //取01#水表的上级分类代号
            if (meterInfoShort.getAnotherName().startsWith("01#")) {
                meter01 = meterInfoShort;
                fac1ProdCode = meterInfoShort.getAreaId();
            }
            //取07#水表的上级分类代号
            if (meterInfoShort.getAnotherName().startsWith("07#")) {
                meter07 = meterInfoShort;
                fac1PubCode = meterInfoShort.getAreaId();
            }
            //取10#新回收房水表的上级分类代号
            if (meterInfoShort.getAnotherName().startsWith("10#")) {
                meter10 = meterInfoShort;
                fac1EnvCode = meterInfoShort.getAreaId();
            }
        }
        for (int i = 1; i < list.size(); i++) {
            Map<String, String> map = list.get(i);
            Double meter07Value = 0d;
            String v0 = map.get(meter07.getDeviceName());
            if (!StringUtils.isBlank(v0)) {
                meter07Value = Double.valueOf(v0);
            }
            Double fac1PubValue = 0d;
            String v1 = map.get(fac1PubCode);
            if (StringUtils.isNotBlank(v1)) {
                fac1PubValue = Double.valueOf(v1);
            }
            Double fac1EnvValue = 0d;
            String v2 = map.get(fac1EnvCode);
            if (StringUtils.isNotBlank(v2)) {
                fac1EnvValue = Double.valueOf(v2);
            }
            Double fac1ProdValue = 0d;
            String v3 = map.get(fac1ProdCode);
            if (StringUtils.isNotBlank(v3)) {
                fac1ProdValue = Double.valueOf(v3);
            }
            //一厂公共用水排除07#水表
            map.put(fac1PubCode, String.valueOf(decimalFormat.format(fac1PubValue - meter07Value)));
            //一厂生产用水排除 一厂环保用水和07#水表
            map.put(fac1ProdCode, String.valueOf(decimalFormat.format(fac1ProdValue - fac1EnvValue - meter07Value)));
        }
        //endregion

        return list;
    }

    public List<String> getDates(String startDate, String endDate) {
        //region 构造日期列表
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date fromDate = new Date();
        Date toDate = fromDate;
        try {
            fromDate = simpleDateFormat.parse(startDate);
            toDate = simpleDateFormat.parse(endDate);
        } catch (ParseException e) {
            //e.printStackTrace();
        }
        List<String> dateList = new LinkedList<>();
        for (Date d = fromDate; d.before(DateUtils.addDays(toDate, 1)); d = DateUtils.addDays(d, 1)) {
            dateList.add(simpleDateFormat.format(d));
        }
        //endregion
        return dateList;
    }

    /**
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return Map<日期, Map < 读表器, DIYExportExport>>
     */
    public Map<String, Map<String, DIYRepExport>> mapDIYRepExport(String startDate, String endDate) {
        Map<String, Map<String, DIYRepExport>> tempMap = new HashMap<>();
        DIYRepExport lastMod = null;
        List<MeterInfoShort> shortList = meterMapper.queryMetersInfoShort();
        Map<String, MeterInfoShort> mapTemp = new HashMap<>();
        for (MeterInfoShort meterInfoShort : shortList) {
            mapTemp.put(meterInfoShort.getDeviceName(), meterInfoShort);
        }
        //
        List<DIYRepExport> list = monitorMapper.queryForDIYRep(startDate, endDate);
        //
        Double sumValue = 0d;
        for (int i = 0; i < list.size(); i++) {
            DIYRepExport modRepExport = list.get(i);
            Map<String, DIYRepExport> map = tempMap.get(modRepExport.getUploadDate());
            if (map == null) {
                map = new HashMap<>();
                tempMap.put(modRepExport.getUploadDate(), map);
            }
            //
            MeterInfoShort nowMeterInfoShort = mapTemp.get(modRepExport.getMeterCode());
            if (nowMeterInfoShort == null) {
                continue;
            }
            modRepExport.setMeterName(nowMeterInfoShort.getAnotherName());
            modRepExport.setIsArea(false);
            if (!map.containsKey(modRepExport.getMeterCode())) {
                map.put(modRepExport.getMeterCode(), modRepExport);
            }
            //求各区域累计用水量
            if (!map.containsKey(nowMeterInfoShort.getAreaId())) {
                DIYRepExport modTemp = new DIYRepExport();
                modTemp.setIsArea(true);
                modTemp.setMeterCode(nowMeterInfoShort.getAreaId());
                modTemp.setMeterName(nowMeterInfoShort.getAreaName());
                modTemp.setUploadDate(modRepExport.getUploadDate());
                modTemp.setIntervalQuantity(modRepExport.getIntervalQuantity());
                map.put(nowMeterInfoShort.getAreaId(), modTemp);
            } else {
                DIYRepExport modTemp = map.get(nowMeterInfoShort.getAreaId());
                modTemp.setIntervalQuantity(modTemp.getIntervalQuantity() + modRepExport.getIntervalQuantity());
            }
        }
        //region根据公式修正各个区域的用水量
        for (String strDate : tempMap.keySet()) {
            Map<String, DIYRepExport> meterMap = tempMap.get(strDate);
            DIYRepExport fac1ProdMod = null;
            DIYRepExport fac1EnvMod = null;
            //三厂公共用水
            DIYRepExport fac3PubMod = null;
            //软板公共用水
            DIYRepExport ruanPubMod = null;
            //
            for (String meterCode : meterMap.keySet()) {
                DIYRepExport mod = meterMap.get(meterCode);
                if (mod.getIsArea()) {
                    if (mod.getMeterName().contains("一厂") && mod.getMeterName().contains("环保")) {
                        fac1EnvMod = mod;
                    }
                    if (mod.getMeterName().contains("一厂") && mod.getMeterName().contains("生产")) {
                        fac1ProdMod = mod;
                    }
                    if (mod.getMeterName().contains("软板") && mod.getMeterName().contains("公共")) {
                        ruanPubMod = mod;
                    }
                    if (mod.getMeterName().contains("三厂") && mod.getMeterName().contains("公共")) {
                        fac3PubMod = mod;
                    }
                }
            }
            //
            if (fac1ProdMod != null && fac1EnvMod != null) {
                fac1ProdMod.setIntervalQuantity(fac1ProdMod.getIntervalQuantity() - fac1EnvMod.getIntervalQuantity());
            }
            //三厂公共用水=三厂公共用水(30#) - 软板公共用水用量
            if (fac3PubMod != null && ruanPubMod != null) {
                fac3PubMod.setIntervalQuantity(fac3PubMod.getIntervalQuantity() - ruanPubMod.getIntervalQuantity());
            }
        }
        //endregion
        return tempMap;
    }

    public Map<String, Map<String, MeterInfoShort>> mapAreaMeterInfoShort() {
        Map<String, Map<String, MeterInfoShort>> map = new HashMap<String, Map<String, MeterInfoShort>>();
        List<MeterInfoShort> list = meterMapper.queryMetersInfoShort();
        for (MeterInfoShort meterInfoShort : list) {
            Map<String, MeterInfoShort> mmp = map.get(meterInfoShort.getAreaId());
            if (mmp == null) {
                mmp = new HashMap<String, MeterInfoShort>();
                map.put(meterInfoShort.getAreaId(), mmp);
            }
            if (!mmp.containsKey(meterInfoShort.getDeviceName())) {
                mmp.put(meterInfoShort.getDeviceName(), meterInfoShort);
            }
        }
        return map;
    }

    public void queryDIYRep3(String startDate, String endDate, HttpServletResponse response) {
        //构造日期列表
        List<String> dateList = getDates(startDate, endDate);
        //Map<日期，<读表器，DIYRepExport>>
        Map<String, Map<String, DIYRepExport>> listData = mapDIYRepExport(startDate, endDate);

        Map<String, Map<String, MeterInfoShort>> mapMeterInfo = mapAreaMeterInfoShort();

        List<Area> sortedAreas = areaMapper.getAllAreas();
        //生成Excel文件流
        ExcelUtil.getInstanse().exportDIYReport(meterMapper, sortedAreas, dateList, listData, mapMeterInfo, response);
    }

    public List<ReportShiftly> getReportShiftly(String fromTime, String toTime, String[] device_codes) {
        List<ReportShiftly> lists = new LinkedList<>();
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        try {
            //lists = monitorMapper.getReportDaily(fromDate, toDate, null, anotherNames);
            lists = monitorMapper.getReportShiftly(fromTime, toTime, device_codes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        //
        for (ReportShiftly mod : lists) {
            Double electricQty = mod.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                mod.setElectricQtyShow(electricQty + "%");
            }
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            if ("10".equals(mod.getDayOrNight())) {
                mod.setDayOrNight("白班");
            } else if ("20".equals(mod.getDayOrNight())) {
                mod.setDayOrNight("夜班");
            }
            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(rate));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    public List<ReportShiftly> getReportShiftlySum(String fromTime, String toTime, String[] device_codes) {
        List<ReportShiftly> lists = new LinkedList<>();
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        try {
            lists = monitorMapper.getReportShiftlySum(fromTime, toTime, device_codes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        //
        for (ReportShiftly mod : lists) {
            Double electricQty = mod.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                mod.setElectricQtyShow(electricQty + "%");
            }
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            if ("10".equals(mod.getDayOrNight())) {
                mod.setDayOrNight("白班");
            } else if ("20".equals(mod.getDayOrNight())) {
                mod.setDayOrNight("夜班");
            }
            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(rate));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    public List<ReportHourly> getReportHourlySum(String fromTime, String toTime, String[] device_codes) {
        List<ReportHourly> lists = new LinkedList<>();
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        try {
            //lists = monitorMapper.getReportDaily(fromDate, toDate, null, anotherNames);
            lists = monitorMapper.getReportHourlySum(fromTime, toTime, device_codes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        //
        for (ReportHourly mod : lists) {
            Double electricQty = mod.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                mod.setElectricQtyShow(electricQty + "%");
            }
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(rate));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    public List<ReportHourly> getReportHourly(String fromTime, String toTime, String[] device_codes) {
        List<ReportHourly> lists = new LinkedList<>();
        //double保留2位小数四舍五入
        DecimalFormat df = new DecimalFormat("#0.00");
        try {
            lists = monitorMapper.getReportHourly(fromTime, toTime, device_codes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        DecimalFormat decimalFormat = new DecimalFormat("#0.00");
        //
        for (ReportHourly mod : lists) {
            Double electricQty = mod.getElectricQty();
            if (electricQty != null) {
                electricQty = Double.valueOf(df.format(electricQty));
                mod.setElectricQtyShow(electricQty + "%");
            }
            if (mod.getRealUsage() == null) {
                mod.setRealUsage(0d);
            }
            if (mod.getStandardUsage() == null) {
                mod.setStandardUsage(0D);
            }
            Double currentQuantiry = mod.getCurrentQuantiry();
            if (currentQuantiry != null) {
                currentQuantiry = Double.valueOf(df.format(currentQuantiry));
                mod.setCurrentQuantiry(currentQuantiry);
            }
            mod.setRealUsageShow(df.format(mod.getRealUsage()));
            mod.setStandardUsageShow(df.format(mod.getStandardUsage()));
            //用水节约率
            double rate = 0;
            if (mod.getStandardUsage() > 0) {
                rate = (mod.getStandardUsage() - mod.getRealUsage()) / mod.getStandardUsage();
            }
            mod.setSaveRate(rate);
            mod.setSaveRateShow(new DecimalFormat("#.##%").format(rate));
            //是否超标
            boolean isOF = mod.getRealUsage() > mod.getStandardUsage();
            mod.setOverFlow(isOF);
            mod.setOverFlowName(isOF ? "是" : "否");
            //超标时长
            if (mod.getExceedSec() == null) {
                mod.setExceedSec(Double.valueOf(0));
            }
            mod.setExceedHour(mod.getExceedSec() / 3600);
            mod.setExceedHourShow(decimalFormat.format(mod.getExceedHour()));
        }
        return lists;
    }

    public Date getOfflineTime(){
        String offlineMinutes = resourceConfig.getValueByKey("offline_minutes");
        int minutes = Integer.valueOf(offlineMinutes);
        Calendar instance = Calendar.getInstance();
        instance.add(Calendar.MINUTE,-minutes);
        return instance.getTime();
    }
}
